package cn.wolfcode.wolf2w.service.impl;

import ch.qos.logback.classic.db.DBHelper;
import cn.wolfcode.wolf2w.domain.*;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.query.TravelCondition;
import cn.wolfcode.wolf2w.query.TravelQuery;
import cn.wolfcode.wolf2w.repository.TravelCommentRepository;
import cn.wolfcode.wolf2w.repository.TravelRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.ITravelService;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import com.aliyun.oss.common.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class TravelServiceImpl implements ITravelService {
    @Autowired
    private TravelRepository travelRepository;
    @Autowired
    private TravelCommentRepository commentRepository;

    @Autowired
    private MongoTemplate mongoTemplate;//可以操作数据库

    @Autowired
    private IDestinationService destinationService;//目的地服务类

    @Autowired
    private IUserInfoService userInfoService;



    @Override
    public Travel get(String id) {
        Optional byId = travelRepository.findById(id);
//强转
        return (Travel) byId.orElse(null);//如果是空是就返回空值,否则返回对象
    }

//    @Override
//    public void update(Travel travel) {
//        Travel travel1 = this.get(travel.getId());
//        travel1
//    }
    public Travel saveOrUpdate(Travel travel) {
        // 目的地名称
        Destination destination = destinationService.get(travel.getDestId());
        travel.setDestName(destination.getName());
        // 用户id 表现层的controller以设置

        // 更新时间
        //最后更新时间
        travel.setLastUpdateTime(new Date());
        if (StringUtils.hasLength(travel.getId())){
            // 修改操作 字段
            travel.setTravelTime(travel.getTravelTime());
            travel.setFavornum(travel.getFavornum());
            travel.setReplynum(travel.getReplynum());
            travel.setViewnum(travel.getViewnum());
            travel.setThumbsupnum(travel.getThumbsupnum());
            travel.setSharenum(travel.getSharenum());
            travelRepository.save(travel);
        }else {
            // 创建时间
            travel.setCreateTime(new Date());
            travelRepository.save(travel);
        }
        return travel;
    }

    @Override
    public List<Travel> listAll() {
        List<Travel> travels = travelRepository.findAll();
        return travels;
    }




    @Override
    public Page<Travel> query(TravelQuery qo) {
        //查询对象
        Query query = new Query();


        //查询出总数条数
        long rows = mongoTemplate.count(query, Travel.class);
        if (rows == 0) {
            return  Page.empty();//如果总数条数是0,就返回空集合
        }
        //分页对象(设置当前页从0开始算,还有页面显示条数,按sequence这个列正序排列 )  
        //  Sort.Direction.ASC,表示按正序排列表格
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1,
                qo.getPageSize(), Sort.Direction.ASC, "_id");
        //给查询对象
        query.with(pageable);

//        if(qo.getDayType()==2){
//
//         }

        //生成map对象
        //并且给map对象设值.(并且让过滤条件key和where语句的数字范围(value)对应起来)
        //通过获取对象的getMin()获取范围最大最小值
        TravelCondition day = qo.getDay();//生成map对象
        //对象不等于null,才执行
        if(day!=null){
//            query.addCriteria(Criteria.where("day").gte(day.getMin()).lte(day.getMax()));
            //获取范围最小值
            int min = day.getMin();
            //获取范围最大值
            int max = day.getMax();
            //拼接成sql查询数据库
            //获取查询条件对象
            Criteria criteria = Criteria.where("day").gte(min).lte(max);//大于最小值,小于最大值
            query.addCriteria(criteria);
        }
        List<Travel> list = mongoTemplate.find(query, Travel.class);
        PageImpl<Travel> page = new PageImpl<>(list, pageable, rows);
        List<Travel> travels = page.getContent();
        //  //缺少用户对象 设置结果集合的每个对象的作者属性(userInfo)
        for (Travel travel : travels) {
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);//设置用户名称和头像

        }

        return page ;//相当于pageResult对象

    }
//审核
    @Override
    public void auditState(String id, int state) {
        //通过id-->获取用户点击的那个游记对象(目的是再获取游记的状态字段)
//如果游记id不是空,才执行判断逻辑(就是用户没点击,就不执行判断逻辑)
        //审核操作,其实也是类似修改操作
        if (StringUtils.hasLength(id)) {
           //查询
            Travel travel = this.get(id);
            //如果审核通过
            if (travel.getState()== Travel.STATE_RELEASE) {
                //替换
                // //设置旅游日记状态是审核通过(之前的状态是待审核状态)
                travel.setState(Travel.STATE_RELEASE);
                //设置最后更新时间是此时
                travel.setLastUpdateTime(new Date());
                //设置发布时间是此时
                travel.setReleaseTime(new Date());
                //如果有需求,可以设置记录审核信息(审核人,审核时间,审核状态,审核备注)
                //修改游记表的字段,要更新到数据库
                //更新
                travelRepository.save(travel);

            }else if(travel.getState()== Travel.STATE_REJECT){
                //替换
                // //设置旅游日记状态是审核通过(之前的状态是待审核状态)
                travel.setState(Travel.STATE_REJECT);
                //设置发布时间是空(没有发布,就没有发布时间)
                travel.setReleaseTime(null);
                //设置最后更新时间是此时
                travel.setLastUpdateTime(new Date());
                //更新
                travelRepository.save(travel);
            }else{
                //
                throw new LogicException("游记状态输入不对");
            }
        }
    }
//根据游记id查询单个要游记
    //查询时是关联字段(某类型的字段),没有设置是获取不到
    @Override
    public Travel detail(String id) {
        Travel travel = this.get(id);
//        用户信息
//        不设置游记对象的作者字段,返回到页面,游记是没有作者名字的;是没有作者头像的,还会报错
        travel.setAuthor(userInfoService.get(travel.getUserId()));
        //目的地信息
        Destination dest = destinationService.get(travel.getDestId());
        travel.setDest(dest);//不设置游记对象的目的地字段,返回到页面,是没有目的地名字的 会报错
        return   travel;
    }


}
